# /*
#  * @Author: 周梦泽 
#  * @Date: 2023-03-21 10:02:47 
#  * @Last Modified by:   周梦泽 
#  * @Last Modified time: 2023-03-21 10:02:47
#   此程序用于获取淘宝生意参谋的关键词数据
#  */
import glob
import os
import time
from datetime import datetime

import pandas as pd
import pyautogui
import send2trash
from fuzzywuzzy import fuzz

from autoTask.taobao.sycm.utils.close_Ad import close_ad
from autoTask.taobao.sycm.utils.selectDays import select_days
from autoTask.taobao.taobao_login import Login
from common.logger.log import log_
from common.utils.ExcelUtil import pd_paste_2_csv
from common.utils.ThreadUtil import before_enable_stop_abel_thread
from common.utils.web_page_util import MockTap, Input, random_delay, Tap
from common.utils.web_page_util import create_page
from config import data as yaml_data
from autoTask.taobao.sycm.xgfx import CacheAction

pyautogui.FAILSAFE = False
sycm_url = 'https://sycm.taobao.com/'
# 生意参谋首页url
gjc_download_path = yaml_data.get('download_path.path') + 'gjc/gjc_data/'
hyc_download_path = yaml_data.get('download_path.path') + 'hyc/hyc_data/'

current_dir = os.path.dirname(os.path.abspath(__file__))
date_time_string = datetime.today().strftime('%Y-%m-%d_%H-%M-%S')


class GetData:

    def __init__(self, params: dict):
        """
        初始化参数
        params: 任务参数，包含
                    ['tbAccount': 账号 str,
                   'tbPassword':密码 str,
                   'port': 启动端口号 int,
                   'search_content': 搜索内容 str,
                   'date_cycle': 搜索天数 int,
                   ]
        """
        # 提取参数

        self.account = params['account']
        self.password = params['password']
        # self.port = params['port']
        self.search_content = params['searchContent']
        # self.is_operation_title = params['isOperationTitle']
        # self.is_auto_append_key_word = params['isAutoAppendKeyWord']
        self.date_cycle = params['dateCycle']
        # self.related_day = params['relatedDay']
        # self.hot_term_day = params['hotTermDay']
        self.data_word = params['dataWord']
        self.table_topic_list = params.get('tableTopic')
        self.block_words = params.get('blockWords')
        self.page = create_page()

        self.gjc_file_name = f'gjc_{self.data_word}_{date_time_string}.csv'
        self.hyc_file_name = f'hyc_{self.data_word}_{date_time_string}.csv'
        self.gjc_folder_path = os.path.abspath(os.path.join(current_dir, '../../../../../../' + gjc_download_path))
        self.hyc_folder_path = os.path.abspath(os.path.join(current_dir, '../../../../../../' + hyc_download_path))
        # 保存的文件名与文件路径
        if 'sycm.taobao.com' not in self.page.url:
            self.page, _ = Login(self.account, self.password).execute()
        # 登录淘宝
        # self.ac = ActionChains(self.page)

    @before_enable_stop_abel_thread(target_func=close_ad, is_loop=True)
    def start_run(self):
        """
        启动方法
        开始执行任务 调用action方法 执行任务，失败重试次
        :return:
        """
        date_cycle = self.date_cycle
        log_.info('登录成功,正在执行任务')
        log_.info('正在删除旧文件夹数据(可在垃圾桶回收站找回)')
        csv_folders = [self.gjc_folder_path, self.hyc_folder_path]
        csv_files = [f for folder in csv_folders for f in glob.glob(os.path.join(folder, "*.csv"))]
        for csv_path in csv_files:
            send2trash.send2trash(csv_path)
        page, data = self.hot_search_keywords(self.page)
        page = self.deep_analysis(date_cycle, page, data)

        csv_files = [file for file in os.listdir(self.gjc_folder_path) if file.endswith(".csv")]
        # 获取文件夹下的所有csv文件
        if len(csv_files) > 0:
            log_.info("已转化{}个csv文件".format(len(csv_files)))
            log_.info('任务成功')
        elif len(csv_files) < 10:
            log_.error('任务成功,但是检测到下载到csv文件不足')
            raise Exception('任务成功，但是没检测到下载到csv文件')
        return page

    def hot_search_keywords(self, page):
        """
        提取热门搜索词路径:市场->搜索排行->搜索词->热搜 -> 选择天数 -> 点击搜索词 -> 点击热搜
        """
        log_.info('正在打开生意参谋')
        # 跳转到生意参谋首页
        if sycm_url not in page.url:
            page.get(sycm_url)
            time.sleep(3)
        MockTap('市场', msg='点击市场失败', before_delay=(3, 6))(page)
        MockTap('搜索排行', msg='点击搜索排行失败', before_delay=(3, 6))(page)
        MockTap(ele="x://a[@class='common-picker-header']/span", msg='点击输入品类失败', before_delay=(3, 6))(page)
        Input(ele="x://span[@class='oui-canary-input ant-input-affix-wrapper']/input", vals=self.search_content + '\n',
              before_delay=(3, 6), msg='输入品类失败', after_delay=(5, 8))(page)
        MockTap(ele="x://div[@class='oui-typeahead-dropdown']/div[1]", msg='点击第一个品类失败', before_delay=(3, 6))(
            page)
        log_.info('选择{}天'.format(self.date_cycle))
        page, self.date_cycle = select_days(page, self.date_cycle)
        log_.info('正在点击 搜索词')
        MockTap(ele=self.data_word, msg='点击搜索词失败', before_delay=(3, 6))(page)
        log_.info('正在点击 热搜')
        MockTap(ele='热搜', msg='点击热搜失败', before_delay=(3, 6), after_delay=(3, 6))(page)
        # 获取热门搜索词列表，列表中的每个元素转换为文字需要+.text,例如：hot_term_list[0].text
        if page('正值大促期间数据拥堵，请稍后尝试，感谢配合！', timeout=1):
            random_delay((3, 6))
            page.refresh()  # 刷新页面
        log_.info('点击 小旺神一键转化')
        # self.page('小旺神一键转化').click()
        Tap(ele='小旺神一键转化', msg='没找到元素', before_delay=(1, 2))(page)
        # time.sleep(3)
        log_.info('点击一键复制')
        Tap('一键复制', msg='一键复制失败', before_delay=(1, 2))(page)
        path = self.hyc_folder_path + '\\' + self.search_content + '_' + self.hyc_file_name

        data = self.title_match(path=path)

        log_.info('关闭小旺神')
        time.sleep(1)
        pyautogui.press('esc')

        return page, data

    def deep_analysis(self, date_cycle, page, data, keyword_num=None):
        """
        生意参谋->搜索分析 -> 想关分析 -> 选择天数 -> 小旺神一键转化 -> 一键复制
        :param keyword_num: 添加关键词数量
        :param data: 表格数据
        :param page: 浏览器对象
        :param date_cycle:选择天数
        :return:page 页面对象
        """

        hot_term_list = data['关键词'].tolist()[:keyword_num]
        # 获取关键词列表[:None]全部关键词
        search_jump = page.eles("x://span[@class='sycm-mc-link-td-wrapper horizontal'][1]/a[1]")[0]
        MockTap(search_jump, msg='点击搜索分析失败', before_delay=(3, 6))(page)
        page.set.main_tab(page.to_tab(page.latest_tab))
        # 把最新的标签也改为主标签页
        MockTap('相关分析', msg='点击相关分析失败', before_delay=(3, 6))(page)
        page, date_cycle = select_days(page, date_cycle)
        for i in range(len(hot_term_list)):
            # 循环将词填入搜索框-搜索-点击小旺神一键转化-点击一键复制-更新缓存-写入文件
            # 如果缓存存在，直接写入文件
            path = self.gjc_folder_path + '\\' + hot_term_list[i] + '_' + self.gjc_file_name
            df_result = CacheAction.get_search_key_df(hot_term_list[i], str(self.date_cycle) + '天')
            if df_result is not None:
                # 缓存已存在
                log_.info('缓存已存在，正在写入文件')
                df_result.to_csv(path, index=False)
                continue
            log_.info('正在点击 搜索分析，\n开始搜索第{}'.format(i + 1) + '个热门搜索词:{}'.format(hot_term_list[i]))
            Input("x://span[@class='oui-canary-input ant-input-affix-wrapper']/input", msg='输入热门分析词失败',
                  vals=hot_term_list[i] + '\n', before_delay=(3, 6), after_delay=(3, 6))(page)
            log_.info('数据加载中')
            # MockTap('小旺神一键转化', msg='点击小旺神转化失败', before_delay=(3, 6), reduce_scope=(10, 5))(page)
            Tap('小旺神一键转化', msg='点击小旺神转化失败', before_delay=(1, 2))(page)
            if page('没有可转化的指数！', timeout=2):
                log_.info('没有可转化的指数！')
                continue
            if page('数据更新失败，请刷新页面重试！', timeout=2):
                log_.info('数据更新失败，请刷新页面重试！')
                page.refresh()
            log_.info('点击一键复制')
            Tap(' 一键复制', msg='一键复制失败', before_delay=(1, 2), after_delay=(1, 3))(page)
            log_.info('正在转化数据')

            data = pd_paste_2_csv(path=path)
            # 更新缓存
            CacheAction.put_cache_by_df(hot_term_list[i], str(self.date_cycle) + '天', data, )

            log_.info('转化完成,关闭小旺神')
            time.sleep(1)
            pyautogui.press('esc')
        return page

    def title_match(self, path) -> pd.DataFrame:
        """
        将表格关键词与标题进行匹配，去除不匹配的数据
        :param path: 表格的存储的路径
        :return:
        """
        data = pd_paste_2_csv()

        if self.table_topic_list:
            # 二级标题匹配
            mask = []
            count = 0
            for keyword in data['关键词']:
                if count < 20:
                    mask.append(True)
                    count += 1
                else:
                    # 用一个循环来检查在self.table_topic_list中的任意元素中匹配度是否>=20%,如果有一个匹配度>=20%则返回True
                    contains_topic = False
                    for table_topic in self.table_topic_list:
                        if fuzz.ratio(table_topic, keyword) >= 20:
                            contains_topic = True
                            break
                    # 将检查结果添加到mask列表中
                    mask.append(contains_topic)
            log_.info('执行二级标题匹配')
            # 将不包含主题的数据删除   主题可以有多个
            data = data[mask]
        log_.info('屏蔽关键词')
        mask = False
        for block_word in self.block_words:
            mask |= data['关键词'].str.contains(block_word)
        data = data[~mask]
        data.to_csv(path, index=False)
        return data
